-- SPDX-License-Identifier: GPL-3.0-or-later

local extension = Package("ling9")
extension.extensionName = "lingling"

local U = require "packages/utility/utility"
local LUtil = require "packages/lingling/utility/ling_util"

local nuerhachi = General(extension, "lingling__nuerhachi", "qing", 4)
local tieji = fk.CreateTriggerSkill{
  name = "lingling__tieji",
  anim_type = "offensive",
  events = {fk.TargetSpecified},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and
      data.card.trueName == "slash" and not player.room:getPlayerById(data.to).dead
  end,
  on_cost = function(self, event, target, player, data)
    if player.room:askForSkillInvoke(player, self.name, nil, "#lingling__tieji-invoke::"..data.to) then
      self.cost_data = {tos = {data.to}}
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local to = room:getPlayerById(data.to)
    room:addPlayerMark(to, "@@lingling__tieji-turn")
    for _, s in ipairs(to.player_skills) do
      if s:isPlayerSkill(to) and s.visible then
        room:invalidateSkill(to, s.name, "-turn")
      end
    end
    local judge = {
      who = player,
      reason = self.name,
      pattern = ".",
    }
    room:judge(judge)
    if judge.card.color == Card.Red then
      data.unoffsetableList = data.unoffsetableList or {}
      table.insert(data.unoffsetableList, data.to)
    elseif judge.card.color == Card.Black and not player.dead and not to.dead and not to:isNude() then
      local card = room:askForCardChosen(player, to, "he", self.name, "#lingling__tieji-discard::"..data.to)
      room:throwCard(card, self.name, to, player)
    end
    if to.dead then return end
    if table.find(to.player_skills, function (s)
      return s:isPlayerSkill(to) and s.visible and string.find(Fk:translate(":"..s.name), "受到伤害")
    end) then return end
    local start_id, end_id = 1, 1
    room.logic:getEventsByRule(GameEvent.Turn, 1, function (e)
      if e.data[1] == player then
        start_id, end_id = e.id, e.end_id
        return true
      end
    end, 1)
    if start_id > 1 then
      if #room.logic:getEventsByRule(GameEvent.Damage, 1, function (e)
        if e.id <= end_id then
          local damage = e.data[1]
          return damage.from == player and damage.to == to and damage.card and damage.card.trueName == "slash"
        end
      end, start_id) == 0 then
        room:addPlayerMark(to, self.name, 1)
      end
    end
  end,

  refresh_events = {fk.TurnStart},
  can_refresh = function (self, event, target, player, data)
    return target == player and player:getMark(self.name) > 0
  end,
  on_refresh = function (self, event, target, player, data)
    local room = player.room
    room:setPlayerMark(player, self.name, 0)
    room:addPlayerMark(player, "@@lingling__tieji-turn")
    for _, s in ipairs(player.player_skills) do
      if s:isPlayerSkill(player) and s.visible then
        room:invalidateSkill(player, s.name, "-turn")
      end
    end
  end,
}
local zhulu = fk.CreateTriggerSkill{
  name = "lingling__zhulu",
  anim_type = "offensive",
  frequency = Skill.Compulsory,
  events = {fk.TurnEnd},
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(self) then
      local room = player.room
      if #table.filter(room.discard_pile, function (id)
        return table.contains({Card.SubtypeOffensiveRide, Card.SubtypeDefensiveRide}, Fk:getCardById(id).sub_type)
      end) > 2 then
        return true
      end
      if #table.filter(player:getCardIds("e"), function (id)
        return table.contains({Card.SubtypeOffensiveRide, Card.SubtypeDefensiveRide}, Fk:getCardById(id).sub_type)
      end) > 1 and player:canUse(Fk:cloneCard("slash"), {bypass_times = true}) then
        return true
      end
      if table.find(room:getBanner("@$CenterArea"), function (id)
        return table.contains({Card.SubtypeOffensiveRide, Card.SubtypeDefensiveRide}, Fk:getCardById(id).sub_type)
      end) then
        return true
      end
      if not table.find(room.draw_pile, function (id)
        return table.contains({Card.SubtypeOffensiveRide, Card.SubtypeDefensiveRide}, Fk:getCardById(id).sub_type)
      end) and
        #room.logic:getEventsOfScope(GameEvent.Death, 1, function (e)
          local death = e.data[1]
          return death.damage and death.damage.from == player
        end, Player.HistoryTurn) > 0 then
        return true
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if #table.filter(room.discard_pile, function (id)
      return table.contains({Card.SubtypeOffensiveRide, Card.SubtypeDefensiveRide}, Fk:getCardById(id).sub_type)
    end) > 2 then
      player:drawCards(1, self.name)
      if player.dead then return end
    end
    if #table.filter(player:getCardIds("e"), function (id)
      return table.contains({Card.SubtypeOffensiveRide, Card.SubtypeDefensiveRide}, Fk:getCardById(id).sub_type)
    end) > 1 and player:canUse(Fk:cloneCard("slash"), {bypass_times = true}) then
      U.askForUseVirtualCard(room, player, "slash", nil, self.name, "#lingling__zhulu-slash", true, true, false, true)
      if player.dead then return end
    end
    local cards = table.filter(room:getBanner("@$CenterArea"), function (id)
      return table.contains({Card.SubtypeOffensiveRide, Card.SubtypeDefensiveRide}, Fk:getCardById(id).sub_type)
    end)
    if #cards > 0 then
      cards = U.askforChooseCardsAndChoice(player, cards, {"OK"}, self.name, "#lingling__zhulu-prey")
      room:moveCardTo(cards, Card.PlayerHand, player, fk.ReasonJustMove, self.name, nil, true, player.id)
    end
    if not table.find(room.draw_pile, function (id)
      return table.contains({Card.SubtypeOffensiveRide, Card.SubtypeDefensiveRide}, Fk:getCardById(id).sub_type)
    end) and
      #room.logic:getEventsOfScope(GameEvent.Death, 1, function (e)
        local death = e.data[1]
        return death.damage and death.damage.from == player
      end, Player.HistoryTurn) > 0 then
      Fk.skills["lianpo"]:doCost(event, target, player, data)
    end
  end,
}
zhulu.CenterArea = true
nuerhachi:addSkill(tieji)
nuerhachi:addSkill(zhulu)
Fk:loadTranslationTable{
  ["lingling__nuerhachi"] = "努尔哈赤",
  ["#lingling__nuerhachi"] = "老罕王",
  ["illustrator:lingling__nuerhachi"] = "珊瑚虫",
  ["designer:lingling__nuerhachi"] = "伶",

  ["lingling__tieji"] = "铁骑",
  [":lingling__tieji"] = "当你使用【杀】指定目标后，你可以令其所有技能本回合无效，然后你判定，若为红色则无法抵消，若为黑色则你弃置其一张牌。"..
  "若其没有描述包含“受到伤害”的技能，且你上回合未使用【杀】对其造成伤害，其下回合所有技能无效。",
  ["lingling__zhulu"] = "逐鹿",
  [":lingling__zhulu"] = "回合结束时，若弃牌堆有至少三张坐骑牌，你摸一张牌；若你装备区有至少两张坐骑牌，你视为使用一张【杀】；"..
  "若中央区有至少一张坐骑牌，你获得其中一张；若牌堆没有坐骑牌，则满足条件你可以发动〖连破〗。"..
  "<br><br> <font color = '#a40000'>奴酋能强能弱，诡谲而难驭也。",
  ["#lingling__tieji-invoke"] = "铁骑：是否对 %dest 发动“铁骑”，令其技能失效并判定？",
  ["@@lingling__tieji-turn"] = "铁骑",
  ["#lingling__tieji-discard"] = "铁骑：弃置 %dest 一张牌",
  ["#lingling__zhulu-slash"] = "逐鹿：视为使用一张【杀】",
  ["#lingling__zhulu-prey"] = "逐鹿：获得其中一张牌",
}

local duoergun = General(extension, "lingling__duoergun", "qing", 4)
local lixing = fk.CreateTriggerSkill{
  name = "lingling__lixing",
  anim_type = "drawcard",
  frequency = Skill.Compulsory,
  events = {fk.Damage},
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(self) and data.to ~= player then
      return table.find(data.to:getCardIds("h"), function (id)
        return Fk:getCardById(id).trueName == "jink" or Fk:getCardById(id).trueName == "nullification"
      end) and #player.room.logic:getActualDamageEvents(2, function(e)
        return e.data[1].from == player and e.data[1].to ~= player
      end) == 1
    end
  end,
  on_use = function(self, event, target, player, data)
    player:drawCards(2, self.name)
  end,
}
local tongwei = fk.CreateActiveSkill{
  name = "lingling__tongwei",
  anim_type = "control",
  card_num = 0,
  target_num = 1,
  prompt = "#lingling__tongwei",
  interaction = function()
    local cards = table.simpleClone(Fk:currentRoom().draw_pile)
    table.insertTable(cards, table.simpleClone(Fk:currentRoom().discard_pile))
    local choices = {}
    for _, name in ipairs({"jink", "nullification"}) do
      if table.find(cards, function (id)
        return Fk:getCardById(id).trueName == name
      end) then
        table.insert(choices, name)
      end
    end
    if #choices == 0 then return end
    return U.CardNameBox { choices = choices, all_choices = {"jink", "nullification"} }
  end,
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) < 2 and
      (table.find(Fk:currentRoom().draw_pile, function (id)
        return table.contains({"jink", "nullification"}, Fk:getCardById(id).trueName)
      end) or table.find(Fk:currentRoom().discard_pile, function (id)
        return table.contains({"jink", "nullification"}, Fk:getCardById(id).trueName)
      end))
  end,
  card_filter = Util.FalseFunc,
  target_filter = function(self, to_select, selected, selected_cards)
    return #selected == 0 and to_select ~= Self.id and
      not table.contains(Self:getTableMark("lingling__tongwei-phase"), to_select)
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local target = room:getPlayerById(effect.tos[1])
    room:addTableMark(player, "lingling__tongwei-phase", target.id)
    local name = self.interaction.data
    local card = room:getCardsFromPileByRule(name, 1, "allPiles")
    if #card == 0 then return end
    room:moveCardTo(card, Card.PlayerHand, target, fk.ReasonJustMove, self.name, nil, true, player.id)
    if target.dead then return end
    room:addPlayerMark(target, "@@lingling__tongwei_"..name, 1)
    if not player.dead then
      room:addTableMark(player, self.name, {target.id, name})
    end
  end,

  on_lose = function (self, player, is_death)
    if is_death then
      local room = player.room
      local mark = player:getTableMark(self.name)
      room:setPlayerMark(player, self.name, 0)
      for _, info in ipairs(mark) do
        local p = room:getPlayerById(info[1])
        if not p.dead then
          dbg()
          room:removePlayerMark(p, "@@lingling__tongwei_"..info[2], 1)
        end
      end
    end
  end,
}
local tongwei_delay = fk.CreateTriggerSkill{
  name = "#lingling__tongwei_delay",
  anim_type = "control",
  events = {fk.CardUseFinished},
  can_trigger = function (self, event, target, player, data)
    return table.find(player:getTableMark("lingling__tongwei"), function (dat)
      return dat[1] == target.id and dat[2] == data.card.trueName
    end) and not target.dead
  end,
  on_cost = Util.TrueFunc,
  on_use = function (self, event, target, player, data)
    local room = player.room
    room:doIndicate(player.id, {target.id})
    room:setPlayerMark(target, "@@lingling__tongwei_"..data.card.trueName, 0)
    local mark = player:getTableMark("lingling__tongwei")
    for i = #mark, 1, -1 do
      if mark[i][1] == target.id and mark[i][2] == data.card.trueName then
        table.remove(mark, i)
      end
    end
    room:setPlayerMark(player, "lingling__tongwei", mark)
    if not target:isNude() then
      local cards = room:askForCardsChosen(player, target, 1, 2, "he", "lingling__tongwei", "#lingling__tongwei-prey::"..target.id)
      room:moveCardTo(cards, Card.PlayerHand, player, fk.ReasonPrey, "lingling__tongwei", nil, false, player.id)
    end
  end,

  refresh_events = {fk.TurnStart},
  can_refresh = function(self, event, target, player, data)
    return target == player and player:getMark("lingling__tongwei") ~= 0
  end,
  on_refresh = function(self, event, target, player, data)
    local room = player.room
    local mark = player:getTableMark("lingling__tongwei")
    room:setPlayerMark(player, "lingling__tongwei", 0)
    for _, info in ipairs(mark) do
      local p = room:getPlayerById(info[1])
      if not p.dead then
        room:removePlayerMark(p, "@@lingling__tongwei_"..info[2], 1)
      end
    end
  end,
}
tongwei:addRelatedSkill(tongwei_delay)
duoergun:addSkill(lixing)
duoergun:addSkill(tongwei)
Fk:loadTranslationTable{
  ["lingling__duoergun"] = "多尔衮",
  ["#lingling__duoergun"] = "墨尔根戴青",
  ["illustrator:lingling__duoergun"] = "珊瑚虫",
  ["designer:lingling__duoergun"] = "伶",

  ["lingling__lixing"] = "厉行",
  [":lingling__lixing"] = "当你每回合首次对其他角色造成伤害后，若其手牌中有【闪】或【无懈可击】，你摸两张牌。",
  ["lingling__tongwei"] = "统围",
  [":lingling__tongwei"] = "出牌阶段限两次，你可以令一名本回合未选择过的其他角色获得一张【闪】或【无懈可击】，直到你下回合开始，"..
  "当其下一次使用同名牌后，你获得其一或两张牌。"..
  "<br><br> <font color = '#a40000'>攻城必克，野战必胜。扫荡贼氛，肃清宫禁。",
  ["#lingling__tongwei"] = "统围：令一名角色获得一张【闪】或【无懈可击】，其下次使用同名牌后你获得其一至两张牌",
  ["@@lingling__tongwei_jink"] = "统围 闪",
  ["@@lingling__tongwei_nullification"] = "统围 无懈可击",
  ["#lingling__tongwei_delay"] = "统围",
  ["#lingling__tongwei-prey"] = "统围：获得 %dest 一至两张牌",
}

local wusangui = General(extension, "lingling__wusangui", "qing", 4)
local huoshui = fk.CreateTriggerSkill{
  name = "lingling__huoshui",
  anim_type = "control",
  frequency = Skill.Compulsory,
  events = {fk.GameStart, fk.AfterCardsMove},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      if event == fk.GameStart then
        local card = table.find(U.prepareDeriveCards(player.room, {{"lingling__chenyuanyuan", Card.Spade, 2}}, self.name), function (id)
          return player.room:getCardArea(id) == Card.Void
        end)
        return card and U.canMoveCardIntoEquip(player, card)
      elseif event == fk.AfterCardsMove and player:getMark(self.name) == 0 then
        for _, move in ipairs(data) do
          if move.from == player.id then
            if (move.moveReason == fk.ReasonDiscard and move.proposer and move.proposer ~= player.id) or
              (move.to and move.to ~= player.id) then
              for _, info in ipairs(move.moveInfo) do
                if info.cardId == U.prepareDeriveCards(player.room, {{"lingling__chenyuanyuan", Card.Spade, 2}}, self.name)[1] then
                  return true
                end
              end
            end
          end
        end
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.GameStart then
      local card = table.find(U.prepareDeriveCards(room, {{"lingling__chenyuanyuan", Card.Spade, 2}}, self.name), function (id)
        return room:getCardArea(id) == Card.Void
      end)
      if card then
        room:setCardMark(Fk:getCardById(card), MarkEnum.DestructIntoDiscard, 1)
        room:moveCardIntoEquip(player, card, self.name, true, player.id)
      end
    elseif event == fk.AfterCardsMove then
      room:setPlayerMark(player, self.name, 1)
      room:doIndicate(player.id, table.map(room:getOtherPlayers(player), Util.IdMapper))
      for _, p in ipairs(room:getOtherPlayers(player)) do
        if not p.dead then
          room:damage{
            from = player,
            to = p,
            damage = 1,
            skillName = self.name,
          }
        end
      end
      for _, p in ipairs(room:getOtherPlayers(player)) do
        if not p.dead then
          room:useVirtualCard("slash", nil, player, p, self.name, true)
        end
      end
    end
  end,
}
local zhuanzhan = fk.CreateTriggerSkill{
  name = "lingling__zhuanzhan",
  anim_type = "control",
  frequency = Skill.Compulsory,
  events = {fk.CardUseFinished},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and data.card.is_damage_card and not data.card.multiple_targets and data.tos and
      table.find(TargetGroup:getRealTargets(data.tos), function (id)
        local p = player.room:getPlayerById(id)
        return p ~= player and not p.dead and p:getMark("@lingling__zhuanzhan") == 0
      end)
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    for _, id in ipairs(TargetGroup:getRealTargets(data.tos)) do
      local p = room:getPlayerById(id)
      if not p.dead and p:getMark("@lingling__zhuanzhan") == 0 then
        room:addPlayerMark(p, "@lingling__zhuanzhan", 1)
      end
    end
  end,
}
local zhuanzhan_delay = fk.CreateTriggerSkill{
  name = "#lingling__zhuanzhan_delay",
  anim_type = "negative",
  events = {fk.CardUsing},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:getMark("@lingling__zhuanzhan") > 0 and data.tos and
      not data.card.multiple_targets and #TargetGroup:getRealTargets(data.tos) == 1 and
      TargetGroup:getRealTargets(data.tos)[1] ~= player.id
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:removePlayerMark(player, "@lingling__zhuanzhan", 1)
    local orig_to = data.tos[1]
    local targets = {}
    local c_pid
    for _, p in ipairs(room.alive_players) do
      if not player:isProhibited(p, data.card) and
      (data.card.sub_type == Card.SubtypeDelayedTrick or data.card.skill:modTargetFilter(p.id, {}, data.from, data.card, true)) then
        local ho_spair_check = true
        if #orig_to > 1 then
          --target_filter check, for collateral, diversion...
          local ho_spair_target = {p.id}
          for i = 2, #orig_to, 1 do
            c_pid = orig_to[i]
            if not data.card.skill:modTargetFilter(c_pid, ho_spair_target, data.from, data.card, true) then
              ho_spair_check = false
              break
            end
            table.insert(ho_spair_target, c_pid)
          end
        end
        if ho_spair_check then
          table.insert(targets, p.id)
        end
      end
    end
    if #targets > 0 then
      local random_target = table.random(targets)
      for i = 1, 2, 1 do
        for _, p in ipairs(room:getAllPlayers()) do
          if table.contains(targets, p.id) then
            room:setEmotion(p, "./image/anim/selectable")
            room:notifyMoveFocus(p, self.name)
            room:delay(300)
          end
        end
      end
      for _, p in ipairs(room:getAllPlayers()) do
        if table.contains(targets, p.id) then
          room:setEmotion(p, "./image/anim/selectable")
          room:delay(600)
          if p.id == random_target then
            room:doIndicate(data.from, {random_target})
            break
          end
        end
      end

      if random_target ~= orig_to[1] then
        orig_to[1] = random_target
        data.tos = { orig_to }
      end
    else
      data.tos = {}
    end
    if player.faceup and math.random() < 0.3 then
      player:turnOver()
    end
  end,
}
zhuanzhan:addRelatedSkill(zhuanzhan_delay)
wusangui:addSkill("yingzi")
wusangui:addSkill(huoshui)
wusangui:addSkill(zhuanzhan)
Fk:loadTranslationTable{
  ["lingling__wusangui"] = "吴三桂",
  ["#lingling__wusangui"] = "窃国巨贼",
  ["illustrator:lingling__wusangui"] = "珊瑚虫",
  ["designer:lingling__wusangui"] = "伶",

  ["lingling__huoshui"] = "祸水",
  [":lingling__huoshui"] = "游戏开始时，将宝物牌【陈圆圆】置入你宝物栏。若你有【陈圆圆】，你视为拥有〖闭月〗。当【陈圆圆】首次"..
  "被其他角色弃置或获得后，你对所有其他角色各造成1点伤害并各视为使用一张【杀】。当【陈圆圆】进入弃牌堆后，销毁之。",
  ["lingling__zhuanzhan"] = "转战",
  [":lingling__zhuanzhan"] = "当你对没有“晕眩”标记的其他角色使用单体伤害牌结算后，其获得一个“晕眩”标记。当有“晕眩”标记的角色使用目标为"..
  "其他角色的单体牌时，其移除一个“晕眩”标记，然后其无视距离随机指定目标，且其有30%几率翻至背面。"..
  "<br><br> <font color = '#a40000'>丹心早为红颜改，青史难宽白发人。",
  ["@lingling__zhuanzhan"] = "晕眩",
  ["#lingling__zhuanzhan_delay"] = "转战",
}

local huangtaiji = General(extension, "lingling__huangtaiji", "qing", 4)
local gulve = fk.CreateActiveSkill{
  name = "lingling__gulve",
  anim_type = "drawcard",
  prompt = function ()
    return "#lingling__gulve:::"..(#Self:getCardIds("e") + 2)
  end,
  card_num = function ()
    if Self:getHandcardNum() > #Self:getCardIds("e") + 2 then
      return Self:getHandcardNum() - #Self:getCardIds("e") - 2
    else
      return 0
    end
  end,
  target_num = 0,
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0 and player:getHandcardNum() ~= #player:getCardIds("e") + 2
  end,
  card_filter = function(self, to_select, selected)
    if Self:getHandcardNum() > #Self:getCardIds("e") + 2 then
      return #selected < Self:getHandcardNum() - #Self:getCardIds("e") - 2 and table.contains(Self:getCardIds("h"), to_select) and
        not Self:prohibitDiscard(to_select)
    else
      return false
    end
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    if #effect.cards == 0 then
      player:drawCards(#player:getCardIds("e") + 2 - player:getHandcardNum(), self.name)
    else
      room:throwCard(effect.cards, self.name, player, player)
      if #effect.cards > 1 and player:isWounded() and not player.dead then
        room:recover{
          who = player,
          num = 1,
          recoverBy = player,
          skillName = self.name,
        }
      end
    end
  end
}
local lanqi = fk.CreateTriggerSkill{
  name = "lingling__lanqi",
  events = {fk.BeforeDrawCard},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and
      table.find(player.room.alive_players, function (p)
        if not table.contains(player:getTableMark(self.name), p.id) then
          if p == player then
            return #player:getCardIds("ej") >= data.num
          else
            return #p:getCardIds("hej") >= data.num
          end
        end
      end)
  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    local targets = table.filter(room.alive_players, function (p)
      if not table.contains(player:getTableMark(self.name), p.id) then
        if p == player then
          return #player:getCardIds("ej") >= data.num
        else
          return #p:getCardIds("hej") >= data.num
        end
      end
    end)
    local to = room:askForChoosePlayers(player, table.map(targets, Util.IdMapper), 1, 1,
      "#lingling__lanqi-choose:::"..data.num, self.name, true, false)
    if #to > 0 then
      self.cost_data = {tos = to}
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local to = room:getPlayerById(self.cost_data.tos[1])
    local flag = "hej"
    if to == player then
      flag = "ej"
    end
    local cards = room:askForCardsChosen(player, to, data.num, data.num, "hej", flag, "#lingling__lanqi-prey::"..to.id..":"..data.num)
    room:moveCardTo(cards, Card.PlayerHand, player, fk.ReasonPrey, self.name, nil, false, player.id)
    if player.dead or to.dead then return end
    if room:askForSkillInvoke(to, self.name, nil, "#lingling__lanqi-invoke:"..player.id.."::"..#cards) then
      to:drawCards(#cards, self.name)
    else
      room:addTableMark(player, self.name, to.id)
    end
    return true
  end
}
huangtaiji:addSkill(gulve)
huangtaiji:addSkill(lanqi)
Fk:loadTranslationTable{
  ["lingling__huangtaiji"] = "皇太极",
  ["#lingling__huangtaiji"] = "莽天腾苍",
  ["illustrator:lingling__huangtaiji"] = "珊瑚虫",
  ["designer:lingling__huangtaiji"] = "猪＆伶",

  ["lingling__gulve"] = "固略",
  [":lingling__gulve"] = "出牌阶段限一次，你可以将手牌调整至X张（X为你装备区牌数+2），若你以此法弃置至少两张牌，你回复1点体力。",
  ["lingling__lanqi"] = "揽气",
  [":lingling__lanqi"] = "每名角色限一次，当你摸牌时，你可以改为获得一名角色区域内等量的牌，然后其可以摸等量牌令此技能视为未对其发动过。"..
  "<br><br> <font color = '#a40000'>揽辔秋风听野歌，雄图开辟太宗多。<br>遥知王气归辽海，不战中原自倒戈。",
  ["#lingling__gulve"] = "固略：将手牌调整至%arg张，若弃置至少两张牌则回复1点体力",
  ["#lingling__lanqi-choose"] = "揽气：你即将摸%arg张牌，是否改为获得一名角色区域内等量的牌？",
  ["#lingling__lanqi-prey"] = "揽气：获得 %dest 区域内%arg张牌",
  ["#lingling__lanqi-invoke"] = "揽气：你可以摸%arg张牌，或点“取消”令 %src 不能再对你发动“揽气”",
}

local yinzhen = General(extension, "lingling__yinzhen", "qing", 4)
local sumu = fk.CreateTriggerSkill{
  name = "lingling__sumu",
  anim_type = "control",
  events = {fk.RoundStart},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and not player:isNude()
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local success, dat = room:askForUseActiveSkill(player, "lingling__sumu_active", "#lingling__sumu-invoke", true)
    if success and dat then
      self.cost_data = {cards = dat.cards, choice = dat.interaction}
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:setPlayerMark(player, "lingling__sumu_name-round", self.cost_data.choice)
    room:setPlayerMark(player, "lingling__sumu_suit-round", Fk:getCardById(self.cost_data.cards[1]).suit)
    room:setPlayerMark(player, "@lingling__sumu-round",
      {Util.TranslateMapper(self.cost_data.choice), Fk:getCardById(self.cost_data.cards[1]):getSuitString(true)})
    room:recastCard(self.cost_data.cards, player, self.name)
  end,
}
local sumu_delay = fk.CreateTriggerSkill{
  name = "#lingling__sumu_delay",
  anim_type = "offensive",
  events = {fk.CardUseFinished},
  can_trigger = function(self, event, target, player, data)
    if target ~= player then
      if player:getMark("lingling__sumu_name-round") == data.card.trueName and not target.dead and not player:isNude() then
        return true
      end
      if player:getMark("lingling__sumu_suit-round") == data.card.suit and
        table.find(player.room.alive_players, function (p)
          return p:getHandcardNum() > player:getHandcardNum()
        end) then
        return true
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    self.cost_data = nil
    if player:getMark("lingling__sumu_name-round") == data.card.trueName and not target.dead and not player:isNude() then
      local card = room:askForDiscard(player, 1, 1, true, "lingling__sumu", true, nil, "#lingling__sumu-damage::"..target.id, true)
      if #card > 0 then
        self.cost_data = {tos = {target.id}, cards = card}
        return true
      end
    end
    if player:getMark("lingling__sumu_suit-round") == data.card.suit and
      table.find(room.alive_players, function (p)
        return p:getHandcardNum() > player:getHandcardNum()
      end) then
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local yes = player:getMark("lingling__sumu_suit-round") == data.card.suit and
      table.find(room.alive_players, function (p)
        return p:getHandcardNum() > player:getHandcardNum()
      end)
    if self.cost_data then
      room:throwCard(self.cost_data.cards, "lingling__sumu", player, player)
      if not target.dead then
        room:damage{
          from = player,
          to = target,
          damage = 1,
          skillName = "lingling__sumu",
        }
      end
    end
    if yes and not player.dead then
      player:drawCards(1, "lingling__sumu")
    end
  end,
}
local sumu_active = fk.CreateActiveSkill{
  name = "lingling__sumu_active",
  card_num = 1,
  target_num = 0,
  interaction = function()
    local names = {}
    for _, id in ipairs(Fk:getAllCardIds()) do
      local card = Fk:getCardById(id)
      if card.type == Card.TypeTrick then
        table.insertIfNeed(names, card.trueName)
      end
    end
    return U.CardNameBox {choices = names}
  end,
  card_filter = function (self, to_select, selected)
    return #selected == 0
  end,
}
local yanglian = fk.CreateTriggerSkill{
  name = "lingling__yanglian",
  anim_type = "control",
  events = {fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and target.phase == Player.Draw and
      #player.room.logic:getEventsOfScope(GameEvent.UseCard, 1, function(e)
        local use = e.data[1]
        return use.from == target.id and table.contains({"ex_nihilo", "snatch"}, use.card.trueName)
      end, Player.HistoryGame) == 0
  end,
  on_cost = function(self, event, target, player, data)
    return player.room:askForSkillInvoke(player, self.name, nil, "#lingling__yanglian-invoke::"..target.id)
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local n = table.find(room.discard_pile, function (id)
      return Fk:getCardById(id).trueName == "ex_nihilo"
    end) and table.find(room.discard_pile, function (id)
      return Fk:getCardById(id).trueName == "snatch"
    end) and 1 or 2
    player:drawCards(n, self.name)
    if not player.dead and not player:isNude() then
      local card = room:askForCard(player, 1, 1, true, self.name, false, nil, "#lingling__yanglian-put")
      room:moveCards({
        ids = card,
        from = player.id,
        toArea = Card.DrawPile,
        moveReason = fk.ReasonPut,
        skillName = self.name,
      })
    end
  end,
}
Fk:addSkill(sumu_active)
sumu:addRelatedSkill(sumu_delay)
yinzhen:addSkill(sumu)
yinzhen:addSkill(yanglian)
Fk:loadTranslationTable{
  ["lingling__yinzhen"] = "雍正",
  ["#lingling__yinzhen"] = "朝乾夕惕",
  ["illustrator:lingling__yinzhen"] = "珊瑚虫",
  ["designer:lingling__yinzhen"] = "伶",

  ["lingling__sumu"] = "肃穆",
  [":lingling__sumu"] = "轮次开始时，你可以重铸一张牌，然后声明一种锦囊牌，本轮当一名其他角色：使用该锦囊牌后，你可以弃置一张牌"..
  "对其造成1点伤害；使用与重铸牌花色相同的牌后，若你手牌不为最多，你摸一张牌。",
  ["lingling__yanglian"] = "养廉",
  [":lingling__yanglian"] = "未使用过【无中生有】或【顺手牵羊】的角色摸牌阶段摸牌时，你可以摸一张牌并将一张牌置于牌堆顶，若弃牌堆"..
  "没有这两种牌，则摸一张牌改为摸两张牌。"..
  "<br><br> <font color = '#a40000'>朕昔在雍邸，自幸为天下第一闲人。",
  ["lingling__sumu_active"] = "肃穆",
  ["#lingling__sumu-invoke"] = "肃穆：重铸一张牌并声明一种锦囊牌，根据牌名和重铸牌花色本轮获得效果",
  ["@lingling__sumu-round"] = "肃穆",
  ["#lingling__sumu_delay"] = "肃穆",
  ["#lingling__sumu-damage"] = "肃穆：是否弃一张牌，对 %dest 造成1点伤害？",
  ["#lingling__yanglian-invoke"] = "养廉：%dest 摸牌阶段，你是否摸牌并将一张牌置于牌堆顶？",
  ["#lingling__yanglian-put"] = "养廉：请将一张牌置于牌堆顶",
}

local fukangan = General(extension, "lingling__fukangan", "qing", 4)
local pingpanf = fk.CreateTriggerSkill{
  name = "lingling__pingpanf",
  anim_type = "drawcard",
  frequency = Skill.Compulsory,
  events = {fk.GameStart, fk.BeforeDrawCard},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      if event == fk.GameStart then
        return #player.room.draw_pile > 1
      elseif event == fk.BeforeDrawCard then
        return target == player and data.num > 0
      end
    end
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    if event == fk.GameStart then
      local cards = table.random(room.draw_pile, 100)
      room:moveCardTo(cards, Card.DiscardPile, nil, fk.ReasonDiscard, self.name, nil, true)
    else
      local cards = table.random(room.discard_pile, data.num + 1)
      data.num = 0
      if #cards > 0 then
        room:moveCardTo(cards, Card.PlayerHand, player, fk.ReasonJustMove, self.name, nil, true, player.id)
      end
    end
  end,
}
local caiyou = fk.CreateTriggerSkill{
  name = "lingling__caiyou",
  anim_type = "drawcard",
  events = {fk.CardUseFinished},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and data.card.type == Card.TypeTrick and not player:isNude()
  end,
  on_cost = function (self, event, target, player, data)
    local cards = player.room:askForDiscard(player, 1, 1, true, self.name, true, nil, "#lingling__caiyou-invoke", true)
    if #cards > 0 then
      self.cost_data = {cards = cards}
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:throwCard(self.cost_data.cards, self.name, player, player)
    if not player.dead then
      Fk.skills["luoshen"]:use(event, target, player, data)
    end
  end,
}
local caiyou_obtain = fk.CreateTriggerSkill{
  name = "#lingling__caiyou_obtain",
  mute = true,
  events = {fk.FinishJudge},
  can_trigger = function(self, event, target, player, data)
    return target == player and not player.dead and data.reason == "luoshen" and data.card.color == Card.Black and
    player.room:getCardArea(data.card) == Card.Processing
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    player.room:obtainCard(player.id, data.card)
  end,
}
local gongcheng = fk.CreateTriggerSkill{
  name = "lingling__gongcheng",
  frequency = Skill.Wake,
  events = {fk.AfterDrawPileShuffle},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and player:usedSkillTimes(self.name, Player.HistoryGame) == 0
  end,
  can_wake = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    local room = player.room
    room:handleAddLoseSkills(player, "-lingling__pingpanf|lingling__enchong", nil, true, false)
  end,
}
local enchong = fk.CreateTriggerSkill{
  name = "lingling__enchong",
  anim_type = "drawcard",
  events = {fk.TurnStart, fk.TurnEnd},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self)
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local success, dat = room:askForUseActiveSkill(player, "lingling__enchong_active", "#lingling__enchong-invoke", true)
    if success and dat then
      self.cost_data = {choice = dat.interaction}
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local name = self.cost_data.choice
    room:sendLog({
      type = "#lingling__enchong_choice",
      from = player.id,
      arg = name,
      toast = true,
    })
    local pattern = "."
    if table.find(room.draw_pile, function (id)
      return Fk:getCardById(id).name == name
    end) or table.find(room.discard_pile, function (id)
      return Fk:getCardById(id).name == name
    end) then
      if math.random() < 0.4 then
        pattern = name
      else
        pattern = "^"..name
      end
    end
    local card = room:getCardsFromPileByRule(pattern, 1, "allPiles")
    if #card > 0 then
      room:moveCardTo(card, Card.PlayerHand, player, fk.ReasonJustMove, self.name, nil, pattern == name, player.id)
    end
  end,
}
local enchong_active = fk.CreateActiveSkill{
  name = "lingling__enchong_active",
  card_num = 0,
  target_num = 0,
  interaction = function()
    local names = {}
    for _, id in ipairs(Fk:getAllCardIds()) do
      local card = Fk:getCardById(id)
      if not card.is_derived then
        table.insertIfNeed(names, card.name)
      end
    end
    return U.CardNameBox {choices = names}
  end,
  card_filter = Util.FalseFunc,
}
caiyou:addRelatedSkill(caiyou_obtain)
Fk:addSkill(enchong_active)
fukangan:addSkill(pingpanf)
fukangan:addSkill(caiyou)
fukangan:addSkill(gongcheng)
fukangan:addRelatedSkill("luoshen")
fukangan:addRelatedSkill(enchong)
Fk:loadTranslationTable{
  ["lingling__fukangan"] = "福康安",
  ["#lingling__fukangan"] = "威行海内",
  ["illustrator:lingling__fukangan"] = "珊瑚虫",
  ["designer:lingling__fukangan"] = "伶",

  ["lingling__pingpanf"] = "平叛",
  [":lingling__pingpanf"] = "游戏开始时，弃置牌堆100张牌，当你摸牌时，改为从弃牌堆随机获得X张牌（X为摸牌数+1）。",
  ["lingling__caiyou"] = "才猷",
  [":lingling__caiyou"] = "当你使用锦囊牌结算后，你可以弃置一张牌发动〖洛神〗。",
  ["lingling__gongcheng"] = "功成",
  [":lingling__gongcheng"] = "觉醒技，当牌堆洗牌后，你失去〖平叛〗，获得〖恩宠〗。",
  ["lingling__enchong"] = "恩宠",
  [":lingling__enchong"] = "回合开始时和回合结束时，你可以声明一张牌，然后你随机获得一张牌，有40%几率是你声明的牌。"..
  "<br><br> <font color = '#a40000'>异姓世臣，叨被至此，本朝第一人也。",
  ["#lingling__caiyou-invoke"] = "才猷：你可以弃置一张牌发动“洛神”",
  ["#lingling__caiyou_obtain"] = "才猷",
  ["lingling__enchong_active"] = "恩宠",
  ["#lingling__enchong-invoke"] = "恩宠：声明一个牌名并随机获得一张牌，有%40几率是你声明的牌",
  ["#lingling__enchong_choice"] = "%from 声明了 %arg",

  ["$lingling__gongcheng1"] = "幸此代君狩西事毕，得以垂名内外，更加眷宠。",
  ["$lingling__gongcheng2"] = "勋宠闾庙，今可延香也。",
}

local heshen = General(extension, "lingling__heshen", "qing", 3)
local sinang = fk.CreateActiveSkill{
  name = "lingling__sinang",
  anim_type = "switch",
  switch_skill_name = "lingling__sinang",
  card_num = 0,
  target_num = 0,
  prompt = function (self)
    local name = Self:getSwitchSkillState(self.name, false) == fk.SwitchYang and "amazing_grace" or "snatch"
    if table.find(Fk:currentRoom().discard_pile, function (id)
      return Fk:getCardById(id).trueName == name
    end) then
      return "#lingling__sinang1:::"..name
    else
      return "#lingling__sinang0:::"..name
    end
  end,
  card_filter = Util.FalseFunc,
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    player:drawCards(1, self.name)
    if player.dead or player:isNude() then return end
    local name = player:getSwitchSkillState(self.name, true) == fk.SwitchYang and "amazing_grace" or "snatch"
    local card = Fk:cloneCard(name)
    card.skillName = self.name
    if not table.find(room.alive_players, function (p)
      return player:canUseTo(card, p)
    end) then return end
    local prompt = table.find(room.discard_pile, function (id)
      return Fk:getCardById(id).trueName == name
    end) and 1 or 0
    local success, dat = room:askForUseActiveSkill(player, "lingling__sinang_viewas",
      "#lingling__sinang"..prompt.."-use:::"..name, false)
    if success and dat then
      card:addSubcards(dat.cards)
      room:useCard{
        from = player.id,
        tos = table.map(dat.targets, function(id) return { id } end),
        card = card,
      }
    end
  end,
}
local sinang_viewas = fk.CreateViewAsSkill{
  name = "lingling__sinang_viewas",
  card_filter = function(self, to_select, selected)
    local name = Self:getSwitchSkillState("lingling__sinang", true) == fk.SwitchYang and "amazing_grace" or "snatch"
    if table.find(Fk:currentRoom().discard_pile, function (id)
      return Fk:getCardById(id).trueName == name
    end) then
      return #selected == 0
    else
      return false
    end
  end,
  view_as = function(self, cards)
    local name = Self:getSwitchSkillState("lingling__sinang", true) == fk.SwitchYang and "amazing_grace" or "snatch"
    local card = Fk:cloneCard(name)
    if table.find(Fk:currentRoom().discard_pile, function (id)
      return Fk:getCardById(id).trueName == name
    end) then
      if #cards ~= 1 then return end
      card:addSubcard(cards[1])
    end
    card.skillName = "lingling__sinang"
    return card
  end,
}
local linglong = fk.CreateTriggerSkill{
  name = "lingling__linglong",
  anim_type = "switch",
  switch_skill_name = "lingling__linglong",
  events = {fk.TurnStart},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self)
  end,
  on_use = function(self, event, target, player, data)
    local mark = "@@lingling__linglong_"..player:getSwitchSkillState(self.name, true, true).."-inhand"
    player:drawCards(1, self.name, "top", mark)
  end,
}
local linglong_filter = fk.CreateFilterSkill{
  name = "#lingling__linglong_filter",
  card_filter = function(self, card, player)
    if table.contains(player:getCardIds("h"), card.id) then
      if card:getMark("@@lingling__linglong_yang-inhand") > 0 then
        return player.phase ~= Player.NotActive
      elseif card:getMark("@@lingling__linglong_yin-inhand") > 0 then
        return player.phase == Player.NotActive
      end
    end
  end,
  view_as = function(self, card)
    return Fk:cloneCard("nullification", card.suit, card.number)
  end,
}
local linglong_maxcards = fk.CreateMaxCardsSkill{
  name = "#lingling__linglong_maxcards",
  exclude_from = function(self, player, card)
    return card:getMark("@@lingling__linglong_yang-inhand") + card:getMark("@@lingling__linglong_yin-inhand") > 0
  end,
}
Fk:addSkill(sinang_viewas)
linglong:addRelatedSkill(linglong_filter)
linglong:addRelatedSkill(linglong_maxcards)
heshen:addSkill(sinang)
heshen:addSkill(linglong)
Fk:loadTranslationTable{
  ["lingling__heshen"] = "和珅",
  ["#lingling__heshen"] = "袖里乾坤",
  ["illustrator:lingling__heshen"] = "珊瑚虫",
  ["designer:lingling__heshen"] = "伶",

  ["lingling__sinang"] = "私囊",
  [":lingling__sinang"] = "转换技，出牌阶段限一次，你可以摸一张牌，然后视为使用①【五谷丰登】②【顺手牵羊】。若弃牌堆有对应牌，则你须用一张牌转化。",
  ["lingling__linglong"] = "玲珑",
  [":lingling__linglong"] = "转换技，回合开始时，你可以摸一张牌，此牌于你①回合内②回合外视为【无懈可击】，且不计入手牌上限。"..
  "<br><br> <font color = '#a40000'>一窝一窝又一窝，十窝八窝千百窝。<br>食尽皇家千钟粟，凤少雀何多。",
  ["#lingling__sinang1"] = "私囊：你可以摸一张牌，然后将一张牌当【%arg】使用",
  ["#lingling__sinang0"] = "私囊：你可以摸一张牌，然后视为使用【%arg】",
  ["#lingling__sinang1-use"] = "私囊：请将一张牌当【%arg】使用",
  ["#lingling__sinang0-use"] = "私囊：请视为使用【%arg】",
  ["lingling__sinang_viewas"] = "私囊",
  ["#lingling__linglong_filter"] = "玲珑",
  ["@@lingling__linglong_yang-inhand"] = "玲珑",
  ["@@lingling__linglong_yin-inhand"] = "玲珑",
}

local niangengyao = General(extension, "lingling__niangengyao", "qing", 4)
local weifu = fk.CreateTriggerSkill{
  name = "lingling__weifu",
  anim_type = "masochism",
  frequency = Skill.Compulsory,
  events = {fk.Damaged},
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(self) then
      if not data.card then
        return table.contains(player:getTableMark("@lingling__weifu"), 4)
      elseif data.card:isVirtual() and #data.card.subcards == 0 then
        return table.contains(player:getTableMark("@lingling__weifu"), 3)
      elseif data.card:isVirtual() and #data.card.subcards > 0 then
        return table.contains(player:getTableMark("@lingling__weifu"), 2)
      elseif not data.card:isVirtual() then
        return table.contains(player:getTableMark("@lingling__weifu"), 1)
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    local n = 0
    if not data.card then
      n = 4
    elseif data.card:isVirtual() and #data.card.subcards == 0 then
      n = 3
    elseif data.card:isVirtual() and #data.card.subcards > 0 then
      n = 2
    elseif not data.card:isVirtual() then
      n = 1
    end
    player:drawCards(n, self.name)
  end,

  on_acquire = function (self, player)
    player.room:setPlayerMark(player, "@lingling__weifu", {4, 3, 2, 1})
  end,
  on_lose = function (self, player)
    player.room:setPlayerMark(player, "@lingling__weifu", 0)
  end,
}
local kuiduo = fk.CreateActiveSkill{
  name = "lingling__kuiduo",
  anim_type = "drawcard",
  card_num = 0,
  target_num = 0,
  prompt = "#lingling__kuiduo",
  interaction = function(self)
    local choices = table.map(Self:getTableMark("@lingling__weifu"), function (n)
      return tostring(n)
    end)
    return UI.ComboBox { choices = choices }
  end,
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0 and
      player:getMark("@lingling__weifu") ~= 0
  end,
  card_filter = Util.FalseFunc,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    room:removeTableMark(player, "@lingling__weifu", tonumber(self.interaction.data))
    if #room.discard_pile > 0 then
      local n = math.min(2, #room.discard_pile)
      local cards = U.askforChooseCardsAndChoice(player, room.discard_pile, {"OK"}, self.name, "#lingling__kuiduo-prey", nil, n, n)
      room:moveCardTo(cards, Card.PlayerHand, player, fk.ReasonJustMove, self.name, nil, true, player.id)
    end
  end,
}
niangengyao:addSkill(weifu)
niangengyao:addSkill(kuiduo)
Fk:loadTranslationTable{
  ["lingling__niangengyao"] = "年羹尧",
  ["#lingling__niangengyao"] = "年大将军",
  ["illustrator:lingling__niangengyao"] = "珊瑚虫",
  ["designer:lingling__niangengyao"] = "伶",

  ["lingling__weifu"] = "威福",
  [":lingling__weifu"] = "当你受到技能伤害后，你摸四张牌。当你受到虚拟牌伤害后，你摸三张牌。当你受到转化牌伤害后，你摸两张牌。"..
  "当你受到非转化实体牌伤害后，你摸一张牌。",
  ["lingling__kuiduo"] = "揆度",
  [":lingling__kuiduo"] = "出牌阶段限一次，你可以移除〖威福〗的一句描述，然后从弃牌堆获得两张牌。"..
  "<br><br> <font color = '#a40000'>年虽跋扈不臣，罹大谴，其兵法之灵变，实不愧一时名将之称。",
  ["@lingling__weifu"] = "威福",
  ["#lingling__kuiduo"] = "揆度：你可以移除〖威福〗的一句描述，然后从弃牌堆获得两张牌",
  ["#lingling__kuiduo-prey"] = "揆度：从弃牌堆获得两张牌",
}

local xuanye = General(extension, "lingling__xuanye", "qing", 4)
local zhili = fk.CreateTriggerSkill{
  name = "lingling__zhili",
  anim_type = "support",
  events = {fk.TurnStart},
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(self) then
      local room = player.room
      local targets = table.map(table.filter(room.alive_players, function (p)
        return not p:isNude()
      end), Util.IdMapper)
      if player:getMark(self.name) ~= 0 then
        local turn_event = room.logic:getCurrentEvent():findParent(GameEvent.Turn, true)
        local id = 0
        room.logic:getEventsByRule(GameEvent.Turn, 1, function (e)
          if e.data[1] == player and turn_event and e.id ~= turn_event.id then
            id = e.id
            return true
          end
        end, 1)
        if player:getMark(self.name)[1] == id then
          table.removeOne(targets, player:getMark(self.name)[2])
        end
      end
      if #targets > 0 then
        self.cost_data = targets
        return true
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    local to = player.room:askForChoosePlayers(player, self.cost_data, 1, 1, "#lingling__zhili-choose", self.name, true)
    if #to > 0 then
      self.cost_data = {tos = to}
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local to = room:getPlayerById(self.cost_data.tos[1])
    local turn_event = room.logic:getCurrentEvent():findParent(GameEvent.Turn, true)
    if turn_event ~= nil then
      room:setPlayerMark(player, self.name, {turn_event.id, to.id})
    end
    local cards = table.filter(to:getCardIds("he"), function (id)
      local card = Fk:cloneCard("ex_nihilo")
      card.skillName = self.name
      card:addSubcard(id)
      return card.skill:canUse(to, card)
    end)
    if #cards == 0 then return end
    local card = room:askForCard(to, 1, 1, true, self.name, false, tostring(Exppattern{ id = cards }), "#lingling__zhili-ask")
    room:useVirtualCard("ex_nihilo", card, to, to, self.name)
  end,
}
local xuefan = fk.CreateActiveSkill{
  name = "lingling__xuefan",
  anim_type = "control",
  card_num = 0,
  target_num = 1,
  prompt = "#lingling__xuefan",
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
  end,
  card_filter = Util.FalseFunc,
  target_filter = function(self, to_select, selected)
    local target = Fk:currentRoom():getPlayerById(to_select)
    return #selected == 0 and target:getHandcardNum() > target.hp and
      not table.contains(Self:getTableMark("lingling__xuefan-turn"), to_select)
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local target = room:getPlayerById(effect.tos[1])
    room:addTableMark(player, "lingling__xuefan-turn", target.id)
    if target == player then
      room:askForDiscard(player, 2, 2, true, self.name, false, nil, "#lingling__xuefan-discard::"..target.id)
    else
      local cards = room:askForCardsChosen(player, target, 2, 2, "he", self.name, "#lingling__xuefan-discard::"..target.id)
      room:throwCard(cards, self.name, target, player)
    end
    if not player.dead and not target.dead and
      room:askForSkillInvoke(player, self.name, nil, "#lingling__xuefan-draw::"..target.id) then
      player:setSkillUseHistory(self.name, 0, Player.HistoryPhase)
      target:drawCards(1, self.name)
    end
  end,
}
local qinzheng = fk.CreateTriggerSkill{
  name = "lingling__qinzheng",
  anim_type = "offensive",
  events = {fk.CardUseFinished},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and data.card.trueName == "slash" and
      table.find(player.room:getBanner("@$CenterArea"), function (id)
        return Fk:getCardById(id).trueName == "jink"
      end) and
      table.find(TargetGroup:getRealTargets(data.tos), function (id)
        return not player.room:getPlayerById(id).dead
      end)
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local targets = table.filter(TargetGroup:getRealTargets(data.tos), function (id)
      return not room:getPlayerById(id).dead
    end)
    local to = room:askForChoosePlayers(player, targets, 1, 1,
      "#lingling__qinzheng-choose", self.name, true)
    if #to > 0 then
      self.cost_data = {tos = to}
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local to = room:getPlayerById(self.cost_data.tos[1])
    room:damage{
      from = player,
      to = to,
      damage = 1,
      skillName = self.name,
    }
    if player.dead or to.dead or to:isKongcheng() then return end
    if #room:askForDiscard(to, 1, 1, false, self.name, true, "jink", "#lingling__qinzheng-damage:"..player.id) > 0 and
      not player.dead then
      room:doIndicate(to.id, {player.id})
      room:damage{
        from = to,
        to = player,
        damage = 1,
        skillName = self.name,
      }
    end
  end,
}
qinzheng.CenterArea = true
xuanye:addSkill(zhili)
xuanye:addSkill(xuefan)
xuanye:addSkill(qinzheng)
Fk:loadTranslationTable{
  ["lingling__xuanye"] = "康熙",
  ["#lingling__xuanye"] = "文殊皇帝",
  ["illustrator:lingling__xuanye"] = "珊瑚虫",
  ["designer:lingling__xuanye"] = "伶",

  ["lingling__zhili"] = "治吏",
  [":lingling__zhili"] = "回合开始时，你可以令一名角色将一张牌当【无中生有】使用，不能连续两回合选择同一名角色。",
  ["lingling__xuefan"] = "削藩",
  [":lingling__xuefan"] = "出牌阶段限一次，你可以弃置一名本回合未选择过的手牌多于体力的角色两张牌，然后你可以令其摸一张牌，重置此技能。",
  ["lingling__qinzheng"] = "亲征",
  [":lingling__qinzheng"] = "当你使用【杀】结算后，若中央区有【闪】，你可以对此【杀】的一名目标造成1点伤害，然后其可以弃置一张【闪】"..
  "对你造成1点伤害。"..
  "<br><br> <font color = '#a40000'>圣祖皇帝深仁厚泽，六十余年朔南暨讫，三代以来所未有今。",
  ["#lingling__zhili-choose"] = "治吏：你可以令一名角色将一张牌当【无中生有】使用",
  ["#lingling__zhili-ask"] = "治吏：请将一张牌当【无中生有】使用",
  ["#lingling__xuefan"] = "削藩：你可以弃置一名手牌多于体力的角色两张牌",
  ["#lingling__xuefan-discard"] = "削藩：弃置 %dest 两张牌",
  ["#lingling__xuefan-draw"] = "削藩：是否令 %dest 摸一张牌以重置“削藩”？",
  ["#lingling__qinzheng-choose"] = "亲征：你可以对一名目标造成1点伤害，然后其可以弃一张【闪】对你造成1点伤害",
  ["#lingling__qinzheng-damage"] = "亲征：你可以弃一张【闪】，对 %src 造成1点伤害",
}

local zuozongtang = General(extension, "lingling__zuozongtang", "qing", 3)
local shoufu = fk.CreateActiveSkill{
  name = "lingling__shoufu",
  anim_type = "control",
  frequency = Skill.Limited,
  card_num = 0,
  target_num = 1,
  prompt = "#lingling__shoufu",
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryGame) == 0
  end,
  card_filter = Util.FalseFunc,
  target_filter = function (self, to_select, selected)
    return #selected == 0 and to_select ~= Self.id and Fk:currentRoom():getPlayerById(to_select):getHandcardNum() > 1
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local target = room:getPlayerById(effect.tos[1])
    local card = room:askForCardChosen(player, target, "he", self.name, "#lingling__shoufu-prey::"..target.id)
    room:moveCardTo(card, Card.PlayerHand, player, fk.ReasonPrey, self.name, nil, false, player.id)
    if not target.dead and not player.dead then
      room:addTableMark(player, self.name, target.id)
      room:setPlayerMark(target, "@@lingling__shoufu", 1)
    end
  end
}
local shoufu_delay = fk.CreateTriggerSkill{
  name = "#lingling__shoufu_delay",
  anim_type = "control",
  events = {fk.AfterCardsMove},
  can_trigger = function(self, event, target, player, data)
    if #player:getTableMark("lingling__shoufu") > 0 then
      for _, move in ipairs(data) do
        if move.to and move.toArea == Player.Hand and
          table.contains(player:getTableMark("lingling__shoufu"), move.to) then
          local p = player.room:getPlayerById(move.to)
          if p.phase ~= Player.Draw and not p.dead then
            for _, info in ipairs(move.moveInfo) do
              if table.contains(p:getCardIds("h"), info.cardId) then
                return true
              end
            end
          end
        end
      end
    end
  end,
  on_trigger = function (self, event, target, player, data)
    local room = player.room
    local targets = {}
    for _, move in ipairs(data) do
      if move.to and move.toArea == Player.Hand and
        table.contains(player:getTableMark("lingling__shoufu"), move.to) then
        local p = room:getPlayerById(move.to)
        if p.phase ~= Player.Draw and not p.dead then
          table.insert(targets, move.to)
        end
      end
    end
    room:sortPlayersByAction(targets)
    for _, id in ipairs(targets) do
      if player.dead then return end
      local p = room:getPlayerById(id)
      if not p.dead then
        self:doCost(event, p, player, data)
      end
    end
  end,
  on_cost = function (self, event, target, player, data)
    self.cost_data = {tos = {target.id}}
    return true
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    local cards = {}
    for _, move in ipairs(data) do
      if move.to == target.id and move.toArea == Player.Hand then
        for _, info in ipairs(move.moveInfo) do
          if table.contains(target:getCardIds("h"), info.cardId) then
            table.insertIfNeed(cards, info.cardId)
          end
        end
      end
    end
    if #cards > 0 then
      local card = room:askForCard(target, 1, 1, false, "lingling__shoufu", false, tostring(Exppattern{ id = cards }),
        "#lingling__shoufu-give:"..player.id)
      room:moveCardTo(card, Card.PlayerHand, player, fk.ReasonGive, "lingling__shoufu", nil, false, target.id)
    end
  end,

  refresh_events = {fk.AfterTurnEnd},
  can_refresh = function(self, event, target, player, data)
    return table.contains(player:getTableMark("lingling__shoufu"), target.id)
  end,
  on_refresh = function (self, event, target, player, data)
    local room = player.room
    room:setPlayerMark(target, "@@lingling__shoufu", 0)
    local mark = player:getTableMark("lingling__shoufu")
    for i = #mark, 1, -1 do
      if mark[i] == target.id then
        table.remove(mark, i)
      end
    end
    room:setPlayerMark(player, "lingling__shoufu", mark)
  end,
}
local zhenya = fk.CreateActiveSkill{
  name = "lingling__zhenya",
  anim_type = "offensive",
  frequency = Skill.Limited,
  card_num = 0,
  target_num = 1,
  prompt = "#lingling__zhenya",
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryGame) == 0
  end,
  card_filter = Util.FalseFunc,
  target_filter = function (self, to_select, selected)
    return #selected == 0 and to_select ~= Self.id and Fk:currentRoom():getPlayerById(to_select).hp > 1
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local target = room:getPlayerById(effect.tos[1])
    room:damage{
      from = player,
      to = target,
      damage = 1,
      skillName = self.name,
    }
    if not target.dead and not player.dead then
      room:addTableMark(player, self.name, target.id)
      room:setPlayerMark(target, "@@lingling__zhenya", 1)
    end
  end
}
local zhenya_delay = fk.CreateTriggerSkill{
  name = "#lingling__zhenya_delay",
  anim_type = "offensive",
  events = {fk.PreHpRecover},
  can_trigger = function(self, event, target, player, data)
    return table.contains(player:getTableMark("lingling__zhenya"), target.id)
  end,
  on_cost = function (self, event, target, player, data)
    self.cost_data = {tos = {target.id}}
    return true
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    room:setPlayerMark(target, "@@lingling__zhenya", 0)
    for _, p in ipairs(room.alive_players) do
      if table.contains(p:getTableMark("lingling__zhenya"), target.id) then
        local mark = p:getTableMark("lingling__zhenya")
        for i = #mark, 1, -1 do
          if mark[i] == target.id then
            table.remove(mark, i)
          end
        end
        room:setPlayerMark(p, "lingling__zhenya", mark)
      end
    end
    return true
  end,

  refresh_events = {fk.AfterTurnEnd},
  can_refresh = function(self, event, target, player, data)
    return table.contains(player:getTableMark("lingling__zhenya"), target.id)
  end,
  on_refresh = function (self, event, target, player, data)
    local room = player.room
    room:setPlayerMark(target, "@@lingling__zhenya", 0)
    local mark = player:getTableMark("lingling__zhenya")
    for i = #mark, 1, -1 do
      if mark[i] == target.id then
        table.remove(mark, i)
      end
    end
    room:setPlayerMark(player, "lingling__zhenya", mark)
  end,
}
local gongqin = fk.CreateTriggerSkill{
  name = "lingling__gongqin",
  anim_type = "masochism",
  frequency = Skill.Compulsory,
  events = {fk.Damaged},
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and
      table.find(player.player_skills, function (s)
        return s.frequency == Skill.Limited
      end)
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local n = #table.filter(player.player_skills, function (s)
      return s.frequency == Skill.Limited
    end)
    local choices = {"lingling__gongqin_draw:::"..n}
    for _, s in ipairs(player.player_skills) do
      if s.frequency == Skill.Limited and player:usedSkillTimes(s.name, Player.HistoryGame) > 0 then
        table.insertIfNeed(choices, s.name)
      end
    end
    local choice = room:askForChoice(player, choices, self.name, "#lingling__gongqin-choice")
    if choice:startsWith("lingling__gongqin_draw") then
      player:drawCards(n, self.name)
    else
      player:setSkillUseHistory(choice, 0, Player.HistoryGame)
    end
  end,
}
shoufu:addRelatedSkill(shoufu_delay)
zhenya:addRelatedSkill(zhenya_delay)
zuozongtang:addSkill(shoufu)
zuozongtang:addSkill(zhenya)
zuozongtang:addSkill(gongqin)
Fk:loadTranslationTable{
  ["lingling__zuozongtang"] = "左宗棠",
  ["#lingling__zuozongtang"] = "天下惜公",
  ["illustrator:lingling__zuozongtang"] = "珊瑚虫",
  ["designer:lingling__zuozongtang"] = "伶",

  ["lingling__shoufu"] = "收复",
  [":lingling__shoufu"] = "限定技，出牌阶段，你可以获得一名手牌多于1的其他角色一张牌，则直到其下回合结束，当其于摸牌阶段外获得牌后须交给"..
  "你其中一张。",
  ["lingling__zhenya"] = "镇压",
  [":lingling__zhenya"] = "限定技，出牌阶段，你可以对一名体力大于1的其他角色造成1点伤害，则直到其下回合结束，当其下一次回复体力时防止之。",
  ["lingling__gongqin"] = "躬亲",
  [":lingling__gongqin"] = "当你受到伤害后，你摸X张牌（X为你的限定技数）或重置一个限定技。"..
  "<br><br> <font color = '#a40000'>为国尽忠，亦以季高为冠。国幸有左宗棠也。",
  ["#lingling__shoufu"] = "收复：获得一名角色一张牌，且其于摸牌阶段外获得牌时须交给你一张！",
  ["#lingling__shoufu-prey"] = "收复：获得 %dest 一张牌",
  ["@@lingling__shoufu"] = "收复",
  ["#lingling__shoufu_delay"] = "收复",
  ["#lingling__shoufu-give"] = "收复：你须交给 %src 其中一张牌",
  ["#lingling__zhenya"] = "镇压：对一名角色造成1点伤害，且防止其回复体力！",
  ["@@lingling__zhenya"] = "镇压",
  ["#lingling__zhenya_delay"] = "镇压",
  ["#lingling__gongqin-choice"] = "躬亲：选择摸牌，或重置一个限定技",
  ["lingling__gongqin_draw"] = "摸%arg张牌",

  ["$lingling__shoufu1"] = "所谓疆边无用，实在荒谬！",
  ["$lingling__shoufu2"] = "今不存边野，则明日之京畿为外贼所侵吞也。",
  ["$lingling__zhenya1"] = "受皇命，扫合诸部，弹压地方！",
  ["$lingling__zhenya2"] = "犬以齿牙事人，拔其牙则乖驯也。",
}

return extension
